package com.katesoft.scale4j.demo.web;

import com.katesoft.scale4j.common.services.IBeanNameReferences;
import com.katesoft.scale4j.demo.domain.ExchangeRate;
import com.katesoft.scale4j.log.LogFactory;
import com.katesoft.scale4j.log.Logger;
import com.katesoft.scale4j.persistent.client.LocalHibernateDaoSupport;
import com.katesoft.scale4j.persistent.types.RevisionData;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.ui.PopupDateField;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;

/** @author kate2007 */
public class XRateApplication extends com.vaadin.Application
{
    private static Logger LOGGER = LogFactory.getLogger(XRateApplication.class);
    private static ClassPathXmlApplicationContext context;

    @Override
    public void init()
    {
        final Window main = new Window("x-rates browser");
        setMainWindow(main);
        setTheme("runo");
        main.addListener(new Window.CloseListener()
        {
            @Override
            public void windowClose(Window.CloseEvent e)
            {
                getMainWindow().getApplication().close();
            }
        });
        if (context == null) {
            context = new ClassPathXmlApplicationContext("META-INF/spring/currencies-app-context.xml");
            context.registerShutdownHook();
        }
        final LocalHibernateDaoSupport hibernateDaoSupport = (LocalHibernateDaoSupport) context.getBean(IBeanNameReferences.HIBERNATE_DAO_SUPPORT);
        final Table table = new Table();
        table.setCaption("x-rates");
        table.addContainerProperty("USD", String.class, null);
        table.addContainerProperty("CURRENCY", String.class, null);
        table.addContainerProperty("RATE", String.class, null);
        final Collection<ExchangeRate> currentRates = hibernateDaoSupport.getLocalHibernateTemplate().loadAll(ExchangeRate.class, true);
        renderTable(table, currentRates);
        final PopupDateField datetime = new PopupDateField("Please select the starting time:");
        datetime.setValue(new java.util.Date());
        datetime.setResolution(PopupDateField.RESOLUTION_DAY);
        datetime.addListener(new ValueChangeListener()
        {
            @Override
            public void valueChange(ValueChangeEvent event)
            {
                if (event.getProperty().getValue() != null) {
                    table.removeAllItems();
                    renderTable(table, loadRateForDate(hibernateDaoSupport, (Date) event.getProperty().getValue(), currentRates));
                }
            }
        });
        datetime.setImmediate(true);
        VerticalLayout verticalLayout = new VerticalLayout();
        verticalLayout.addComponent(datetime);
        verticalLayout.addComponent(table);
        main.addComponent(verticalLayout);
    }

    protected void renderTable(Table table,
                               Collection<ExchangeRate> exchangeRates)
    {
        for (ExchangeRate rate : exchangeRates) {
            LOGGER.info("USD-%s:=>%s", rate.getCurrency().getCode(), rate.getRate().toString());
            table.addItem(new Object[]{"USD", rate.getCurrency().getCode(), rate.getRate().toString()}, rate.getCurrency().getCode());
        }
        table.setPageLength(exchangeRates.size());
    }

    protected Collection<ExchangeRate> loadRateForDate(LocalHibernateDaoSupport hibernateDaoSupport,
                                                       Date date,
                                                       Collection<ExchangeRate> currentRates)
    {
        Collection<Long> uniqueIdentifiers = new LinkedHashSet<Long>();
        Collection<ExchangeRate> rates = new LinkedHashSet<ExchangeRate>();
        for (ExchangeRate currentRate : currentRates) {
            uniqueIdentifiers.add(currentRate.getUniqueIdentifier());
        }
        Collection<RevisionData<ExchangeRate>> values =
            hibernateDaoSupport.latestRevisionForDate(ExchangeRate.class, date, uniqueIdentifiers, "actualDate").values();
        for (RevisionData<ExchangeRate> value : values) {
            rates.add(value.getEntityAtRevision());
        }
        return rates;
    }
}
